namespace Vanilla.UI

import Vanilla

import System
import System.Runtime.InteropServices

// BRUSH
class Brush (IDisposable):
	public Handle as IntPtr
	Disposed = false
	
	// CONSTRUCTOR / DESTRUCTOR
	protected def constructor (h as IntPtr):
		Handle = h
	
	def constructor (canvas as Canvas):
		self(Cairo.Create(canvas.Handle))
	
	def Dispose ():
		Disposed = true
		Cairo.Destroy(Handle)
	
	def destructor ():
		Dispose() unless Disposed
	
	// PROPERTIES
	LineWidth as double:
		get:
			return Cairo.GetLineWidth(Handle)
		set:
			Cairo.SetLineWidth(Handle, value)
	
	ClipArea as Rect:
		get:
			r = Rect()
			Cairo.ClipExtents(Handle, r.X, r.Y, r.X2, r.Y2)
			return r
	
	_colour as Colour
	Colour as Colour:
		set:
			Cairo.SetSourceRGBA(Handle, value.R, value.G, value.B, value.A)
			_colour = value
			_pattern = null
		get:
			return _colour
	
	_font as Font
	Font as Font:
		set:
			Cairo.SelectFontFace(Handle, value.Face, value.Slant, value.Weight)
			Cairo.SetFontSize(Handle, value.Pt)
			_font = value
		get:
			return _font
	
	_pattern as Pattern
	Pattern as Pattern:
		set:
			_pattern = value
			Cairo.SetSource(Handle, value.Handle)
		get:
			return _pattern
	
	// TRANSFORMATION
	def Translate (x as double, y as double):
		Cairo.Translate(Handle, x, y)
	
	def Rotate (r as double):
		Cairo.Rotate(Handle, r)
	
	def Scale (x as double, y as double):
		Cairo.Scale(Handle, x,y)
	
	// DRAWING
	def MoveTo (x as double, y as double):
		Cairo.MoveTo(Handle, x, y)
	
	def RelMoveTo (x as double, y as double):
		Cairo.RelMoveTo(Handle, x, y)
	
	def LineTo (x as double, y as double):
		Cairo.LineTo(Handle, x, y)
	
	def CurveTo (c1_x as double, c1_y as double, c2_x as double, c2_y as double, x as double, y as double):
		Cairo.CurveTo(Handle, c1_x, c1_y, c2_x, c2_y, x, y)
	
	def Draw (r as Rect):
		MoveTo(r.X,r.Y)
		LineTo(r.X,r.Y2)
		LineTo(r.X2,r.Y2)
		LineTo(r.X2,r.Y)
		LineTo(r.X,r.Y)
	
	def ClosePath ():
		Cairo.ClosePath(Handle)
	
	def DrawRoundedRect (rect as Rect, radius as double):
		if radius > rect.Width/2 or radius > rect.Height/2:
			radius = Math.Min(rect.Width, rect.Height)/2
	
		MoveTo(rect.X + radius, rect.Y)
		LineTo(rect.X2 - radius, rect.Y)
		CurveTo(rect.X2, rect.Y, rect.X2, rect.Y + radius, rect.X2, rect.Y + radius)
		LineTo(rect.X2, rect.Y2 - radius)
		CurveTo(rect.X2, rect.Y2, rect.X2 - radius, rect.Y2, rect.X2 - radius, rect.Y2)
		LineTo(rect.X+radius, rect.Y2)
		CurveTo(rect.X, rect.Y2, rect.X, rect.Y2 - radius, rect.X, rect.Y2 - radius)
		LineTo(rect.X, rect.Y + radius)
		CurveTo(rect.X, rect.Y, rect.X + radius, rect.Y, rect.X + radius, rect.Y)
		ClosePath()
	
	def Write (s as string):
		x = Font.Extents(s)
		RelMoveTo(-x.XBearing, -x.YBearing)
		Cairo.ShowText(Handle, s)
	
	// STROKE / FILL / PAINT / CLIP
	def Stroke ():
		Cairo.Stroke(Handle)
	def Fill ():
		Cairo.Fill(Handle)
	def Paint ():
		Cairo.Paint(Handle)
	def Clip ():
		Cairo.Clip(Handle)
	
	def StrokePreserve ():
		Cairo.StrokePreserve(Handle)
	def FillPreserve ():
		Cairo.FillPreserve(Handle)
	def ClipPreserve ():
		Cairo.ClipPreserve(Handle)
		
	// SAVE/RESTORE
	def Save ():
		Cairo.Save(Handle)
	def Restore ():
		Cairo.Restore(Handle)
